package com.hjw.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.hjw.entity.*;
import com.hjw.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author hjw
 * @date 2021年10月04日 16:06
 * @description 购物车控制层
 */
@SaCheckRole("usr")
@RestController
@RequestMapping("/api/cart")
@Slf4j
public class CarController {

    @Autowired
    private CartService cartService;
    @Autowired
    private UserService userService;
    @Autowired
    private BookService bookService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderItemService orderItemService;

    /**
     * <p>1.添加购物车需要获取用户的id</p>
     * <p>2.添加购物车仅可添加一条（数据库的索引创建）</p>
     * <p>3. 购物车中添加商品，需要判断用户是否已经添加过，如果已经添加过，则修改数量，如果没有添加过，则添加一条记录</p>
     * @param bid Integer
     * @return String
     */
    @GetMapping("/add/{bid}") // /api/cart/add/{bid}
    public SaResult addCart(@PathVariable("bid") Integer bid) {
        // 获取图书信息
        Book book = bookService.findById(bid);

        // 封装购物车信息
        Cart cart = new Cart();
        cart.setUid(Integer.parseInt(StpUtil.getLoginId().toString()));
        cart.setBook(book);
        cart.setNum(1);
        cart.setPrice(book.getPrice());

        if (cart.getBook().getStock() == 0){
            log.error("商品：{}，库存不足",cart.getBook());
            return SaResult.get(-200,"库存不足",null);
        }

        try {
            // 添加购物车
            cartService.add(cart);
            return SaResult.get(200,"添加成功",null);
        } catch (Exception e) {
            log.error("添加购物车失败：{}",e.getMessage());
            return SaResult.get(-200,"购物车中，商品已存在！",null);
        }
    }

    @GetMapping("/findAll") // /api/cart/findAll
    public SaResult findAll() {
        // 获取用户信息
        List<Cart> carts = cartService.findByUid(Integer.parseInt(StpUtil.getLoginId().toString()));
        for (Cart cart : carts) {
            if (cart.getBook().getStock() > 0 && cart.getNum() > cart.getBook().getStock()) {
                cart.setNum(cart.getBook().getStock());
            }
        }
        log.info("用户：{} 查询购物车,得到信息：{}",Integer.parseInt(StpUtil.getLoginId().toString()),carts);
        return SaResult.get(200,"查询成功",carts);
    }

    @GetMapping("/delete/{id}") // /api/cart/delete/{id}
    public SaResult deleteCart(@PathVariable("id") Integer id) {

        // 获取用户信息
        int uid = Integer.parseInt(StpUtil.getLoginId().toString());

        Cart cart = cartService.findById(id);

        if (cart == null){
            return SaResult.get(-200,"购物车中没有该商品",null);
        }

        if (!cart.getUid().equals(uid)){
            return SaResult.get(-200,"该商品不属于您，无法删除",null);
        }
        int d = cartService.delete(id);
        if (d == 0){
            log.error("用户：{}，删除购物车失败",uid);
            return SaResult.get(-200,"删除失败",null);
        }
        log.info("用户：{}，删除购物车成功",uid);
        return SaResult.get(200,"删除成功",cartService.findByUid(uid));
    }
    // 此处是否需要设置修改购物车信息，因为购物车中不能修改商品信息，只能修改数量
    // 添加为订单时将购物车清空

    @PostMapping("/updateNum") // /api/cart/updateNum
    public SaResult updateNum(@RequestBody List<Cart> carts) {

        // 获取用户信息
        int uid = Integer.parseInt(StpUtil.getLoginId().toString());

        for (Cart cart : carts) {
            cart.setUid(uid);
            if (cartService.update(cart.getUid(),cart.getId(),cart.getNum()) == 0){
                log.error("用户：{}，修改购物车失败",uid);
                return SaResult.get(-200,"购物车中无订单：" + cart.getUid(),null);
            }
        }

        return SaResult.get(200,"修改成功",null);
    }

    @PostMapping("/add2Order")  // /api/cart/add2Order
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public SaResult add2Order(@RequestBody Map<String, Object> map) {
        System.out.println("============================");
        log.info("添加订单：{}",map);
        System.out.println("============================");
        synchronized (this){
        List<Map<String, Object>> carts = (List<Map<String, Object>>) map.get("orders");
        if (carts == null || carts.isEmpty()){
            log.info("订单为空");
            return SaResult.get(-200,"订单为空",null);
        }
        for (Map<String, Object> cart : carts) {
            if (cart.get("id") == null || cart.get("num") == null){
                log.error("订单信息错误");
                return SaResult.get(-200,"订单信息错误",null);
            }
            Map<String,Object> book = (Map<String, Object>) cart.get("book");
            int num =Integer.parseInt(cart.get("num").toString());
            Book b = bookService.findById(Integer.parseInt(book.get("id").toString()));
            if ( num > b.getStock() ){
                return SaResult.get(-200,"无商品"+b.getName()+"库存了",null);
            }
        }
        // 商品总价格
        double amount = Double.parseDouble(map.get("amount").toString());
        String address = map.get("ship2addr").toString();
        String phone = map.get("ship2phone").toString();
        String name = map.get("ship2name").toString();

        //防止跨过前端的再次校验
        if (name == null || phone == null || address == null){
            log.info("发货信息不完整");
            return SaResult.get(-200,"发货信息不完整",null);
        }

        Order order = new Order();
        User user = new User();
        user.setId(Integer.parseInt(StpUtil.getLoginId().toString()));
        order.setOrderItems(null);
        order.setUser(user);
        order.setAmount(amount);
        order.setPayStatus(0);
        order.setTpay(null);
        order.setShipStatus(0);
        order.setShip2name(name);
        order.setShip2phone(phone);
        order.setShip2addr(address);
        order.setTship(null);
        order.setTsign(null);

        int add = orderService.add(order);
        if (add == 0){
            log.error("添加订单失败");
            return SaResult.get(-200,"添加订单失败",null);
        }
        // 获取订单id
        int orderId = order.getOrdid();
        if (orderId == 0){
            log.error("添加订单失败");
            return SaResult.get(-200,"添加订单失败",null);
        }

        for (Map<String, Object> cart : carts) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrdid(orderId);
            orderItem.setBook(new Book());
            Map<String, Object> book = (Map<String, Object>) cart.get("book");
            orderItem.getBook().setId(Integer.parseInt(book.get("id").toString()));
            orderItem.setNum(Integer.parseInt(cart.get("num").toString()));
            orderItem.setPrice(Double.parseDouble(book.get("price").toString()));
            log.info("添加订单项：{}",orderItem);
            int addOrderItem = orderItemService.add(orderItem);
            if (addOrderItem == 0){
                log.error("添加订单失败");
                return SaResult.get(-200,"添加订单失败",null);
            }

            Map<String, Object> b = new HashMap<>(2);
            b.put("id",book.get("id"));
            b.put("stock",-Integer.parseInt(cart.get("num").toString()));
            bookService.update(b);
            log.info("修改库存成功");

            cartService.delete(Integer.parseInt(cart.get("id").toString()));

        }

        return SaResult.get(200,"添加订单成功",orderId);

    }
    }
}
